/*****************************************************************************
 * file  : test.c
 * creat : apleilx
 * data  : 2017/03/02
 *******************************************************************************/
#define __os_obj_creat__
#include "os_obj.h"
#include "bsp_api.h"
#include "common.h"

void os_idle_task_hook(void);
/*----------------------------------------------------------------------------
 * task entry
 *---------------------------------------------------------------------------*/
void task_system(void *argument);
void task_console(void *argument);

/*----------------------------------------------------------------------------
 *   created systask
 *---------------------------------------------------------------------------*/
int os_obj_init(void)
{
	os_obj.tid_systask = &os_obj.tcb_systask;
	rt_thread_init(
		os_obj.tid_systask, "systask",
		task_system, "argv",
		os_obj.stk_systask, SYS_TASK_STK_SIZE,
		SYS_TASK_PRIO, 10);

	rt_thread_startup(os_obj.tid_systask);

	return (0);
}

/*----------------------------------------------------------------------------
 *      systask , create befor os start
 *---------------------------------------------------------------------------*/
int os_thread_init(void)
{
	// rt_thread_idle_sethook(os_idle_task_hook);

	//-------------------------------------------------------------------------

	os_obj.tid_console = &os_obj.tcb_console;
	rt_thread_init(
		os_obj.tid_console, "console",
		task_console, "argv",
		os_obj.stk_console, TASK_COM_CMD_STK_SIZE,
		TASK_COM_CMD_PRIO, 10);

	/*
	os_obj.tid_gui = &os_obj.tcb_gui;
	rt_thread_init(
		os_obj.tid_gui, "console",
		gui_task, "argv",
		os_obj.stk_gui, TASK_GUI_STK_SIZE,
		TASK_GUI_PRIO, 10);

	rt_thread_startup(os_obj.tid_gui);
*/
	rt_thread_startup(os_obj.tid_console);

	return (0);
}

/*----------------------------------------------------------------------------
 *   created in systask
 *---------------------------------------------------------------------------*/
int os_obj_create(void)
{
	// mutex
	os_obj.mid_malloc = &os_obj.mcb_malloc;
	rt_mutex_init(os_obj.mid_malloc, "malloc", RT_IPC_FLAG_PRIO);

	os_obj.mid_printf = &os_obj.mcb_printf;
	rt_mutex_init(os_obj.mid_printf, "print", RT_IPC_FLAG_PRIO);

	// event
	os_obj.sid_modbus = &os_obj.scb_modbus;
	rt_sem_init(os_obj.sid_modbus, "ent mb", 1, RT_IPC_FLAG_PRIO);

	os_thread_init();

	return 0;
}

/*----------------------------------------------------------------------------
 *   os lock
 *---------------------------------------------------------------------------*/
void os_lock(void)
{
	rt_enter_critical();
}

void os_unlock(void)
{
	rt_exit_critical();
}

/*----------------------------------------------------------------------------
 *   task info print
 *---------------------------------------------------------------------------*/
void os_task_info_print(rt_thread_t tid)
{
	int stk, stk_used, pused, prio;
	uu64 *pstk;
	if (!tid)
		return;

	stk = tid->stack_size;
	pstk = (uu64 *)(tid->stack_addr);
	stk_used = 0;
	while (*pstk == 0x2323232323232323)
	{
		stk_used += 8;
		pstk++;
	}

	stk_used = stk - stk_used;
	pused = stk_used * 100 / stk;
	prio = tid->current_priority;

	dbg_print("stack size: %04X, stack used: %4X, <%02d%%>, prio : %2d, <== task: %s\n",
			  stk,
			  stk_used,
			  pused,
			  prio,
			  tid->name);

	(void)pused;
	(void)prio;
}

void os_task_info(void)
{
	dbg_puts("\n===========================================================\n");
	dbg_print("system stack used : %d %%\n", stack_used() / 10);

	// dbg_print("task amount : %d \n", osThreadGetCount());

	os_task_info_print(os_obj.tid_systask);
	os_task_info_print(os_obj.tid_modbus);
	os_task_info_print(os_obj.tid_console);
}
